package com.yeskery.nut.util.executor;

import java.util.concurrent.ExecutorService;
import java.util.function.Function;

/**
 * 执行器工具类
 * @author sunjay
 * 2024/9/1
 */
public class Executors {

    /**
     * 私有化构造方法
     */
    private Executors() {
    }

    /**
     * 创建一个新的单线程执行器
     * @return 新的单线程执行器
     * @param <T> 数据类型
     */
    public static <T> Executor<T> newSingleExecutor() {
        return new ExecutorImpl<>();
    }

    /**
     * 创建一个新的线程池执行器
     * @param executorService 线程池
     * @return 新的线程池执行器
     * @param <T> 数据类型
     */
    public static <T> Executor<T> newExecutorServiceExecutor(ExecutorService executorService) {
        Executor<T> executor = new ExecutorImpl<>();
        executor.setExecutorService(executorService);
        return executor;
    }

    /**
     * 创建一个新的任务对象
     * @param name 任务名称
     * @param retryWaitTimeFunction 重试等待时间函数
     * @return 新的任务对象
     * @param <T> 数据类型
     */
    public static <T> Job<T> newJob(String name, Function<Long, Long> retryWaitTimeFunction) {
        JobImpl<T> job = new JobImpl<>(name);
        job.setRetryWaitTimeFunction(retryWaitTimeFunction);
        return job;
    }

    /**
     * 创建一个新的任务对象
     * @param name 任务名称
     * @return 新的任务对象
     * @param <T> 数据类型
     */
    public static <T> Job<T> newJob(String name) {
        return new JobImpl<>(name);
    }

    /**
     * 创建一个新的任务步骤对象
     * @param name 任务名称
     * @param jobStepExecutor 任务步骤执行接口
     * @return 新的任务对象
     * @param <T> 数据类型
     */
    public static <T> JobStep<T> newJobStep(String name, JobStepExecutor<T> jobStepExecutor) {
        return new JobStepImpl<>(name, jobStepExecutor);
    }

    /**
     * 创建一个固定等待时间重试函数
     * @param waitTime 等待时间
     * @return 固定等待时间重试函数
     */
    public static Function<Long, Long> retryFixedWaitTimeFunction(long waitTime) {
        return t -> waitTime <= 0 ? 3000 : waitTime;
    }

    /**
     * 创建一个固定等待时间重试函数
     * @return 固定等待时间重试函数
     */
    public static Function<Long, Long> retryFixedWaitTimeFunction() {
        return retryFixedWaitTimeFunction(3000L);
    }

    /**
     * 创建一个减半增加等待时间重试函数
     * @param waitTime 第一次等待时间
     * @return 减半增加等待时间重试函数
     */
    public static Function<Long, Long> retryHalfIncrementWaitTimeFunction(long waitTime) {
        return t -> t == null ? (waitTime <= 0 ? 3000 : waitTime) : t + t / 2;
    }

    /**
     * 创建一个减半增加等待时间重试函数
     * @return 减半增加等待时间重试函数
     */
    public static Function<Long, Long> retryHalfIncrementWaitTimeFunction() {
        return retryHalfIncrementWaitTimeFunction(3000L);
    }
}
